package com.ddyx.common.framework.exception;

import com.alibaba.fastjson.JSONObject;
import com.ddyx.common.base.enums.ApiResultType;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.servlet.http.HttpServletRequest;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * 拦截 统一异常处理  应用到所有的控制器上
 * @author agula
 * @date 2019-07-16 13:15
 */
@Slf4j
//@ControllerAdvice(annotations={ExceptionRequired.class})
@RestControllerAdvice //方法上就可以不需要添加 @ResponseBody
public class GlobalExceptionHandler {
	
    @ExceptionHandler(value = Exception.class)
    @ResponseBody
    public Map<String, Object> defaultErrorHandler(HttpServletRequest req, Exception e)  {
    	
      	//打印异常信息：
		log.error(req.getRequestURL().toString(),e);
    	
    	//返回json
    	Map<String, Object> resultMap = new HashMap<>();
		resultMap.put("code", ApiResultType.UNKNOWN_EXCEPTION.getCode());
		resultMap.put("message", ApiResultType.UNKNOWN_EXCEPTION.getMessage());
		resultMap.put("data", new JSONObject());
		return resultMap;
  	}


	/**
	 * 未被关注的异常信息，统一返回给客户端为“系统异常”
	 *
	 */
	@ExceptionHandler(RuntimeException.class)
	@ResponseBody
	public JsonResult handler(RuntimeException e) {
		e.printStackTrace();
		return new JsonResult(-1, "系统异常");
	}

	/**
	 * Hibernate Validator 参数校验异常处理
	 *
	 */
	@ExceptionHandler(MethodArgumentNotValidException.class)
	@ResponseBody
	public JsonResult handler(MethodArgumentNotValidException e) {
		BindingResult bindingResult = e.getBindingResult();
		ObjectError objectError = bindingResult.getAllErrors().get(0);
		return new JsonResult(-1, objectError.getDefaultMessage());
	}

	/**
	 * Spring Validator 参数校验异常处理
	 *
	 */
	@ExceptionHandler(ConstraintViolationException.class)
	@ResponseBody
	public JsonResult handler(ConstraintViolationException e) {
		Set<ConstraintViolation<?>> constraintViolations = e.getConstraintViolations();
		for (ConstraintViolation<?> constraintViolation : constraintViolations) {
			String message = constraintViolation.getMessage();
			if (!StringUtils.isEmpty(message)) {
				//直接返回第一个错误信息
				return new JsonResult(-1, message);
			}
		}
		return new JsonResult(-1, "参数错误");
	}

}